package com.etime.shycourse.services.wxcoupon.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etime.shycourse.dao.*;
import com.etime.shycourse.dto.ActivityAndCouponlist;
import com.etime.shycourse.orde.utils.IdWorker;
import com.etime.shycourse.pojo.*;
import com.etime.shycourse.services.wxcoupon.interfaces.WXActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class WXActivityServiceImpl implements WXActivityService {
    @Autowired
    private CouponactivityMapper couponactivityMapper;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private ActiveLogMapper activeLogMapper;
    @Autowired
    private CouponreciveMapper couponreciveMapper;

    @Autowired
    private CouponlogMapper couponlogMapper;

    /**
     * 获取所有可用的通过分发方式触发的活动列表
     * 活动类型id：1000
     *
     * @return
     */
    @Override
    public List<Couponactivity> getShareActivityList() {
        QueryWrapper<Couponactivity> wrapper = new QueryWrapper<>();
        //活动类型为1000-通过活动链接分享类型
        wrapper.eq("activetypeid", 1000);
        //活动必须时已发布的活动
        wrapper.eq("activestate", 2);
        //活动必须是已经开始，并且未结束的
        Date now = new Date();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String strnow = df.format(now);
        wrapper.le("activebegin", strnow);
        //结束日期应该要在当前时间-1天
        wrapper.ge("activeend", strnow);
        return couponactivityMapper.selectList(wrapper);
    }

    /**
     * 根据优惠券发放方式id查询所有可用的活动列表
     *
     * @param activitytypeid
     * @return
     */
    @Override
    public List<Couponactivity> getUsedActivityListByTypeId(Integer activitytypeid) {
        QueryWrapper<Couponactivity> wrapper = new QueryWrapper<>();
        //活动类型为1000-通过活动链接分享类型
        wrapper.eq("activetypeid", activitytypeid);
        //活动必须时已发布的活动
        wrapper.eq("activestate", 2);
        //活动必须是已经开始，并且未结束的
        //只判断日期
        Date now = new Date();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String strnow = df.format(now);
        wrapper.le("activebegin", strnow);
        wrapper.ge("activeend", strnow);
        return couponactivityMapper.selectList(wrapper);
    }

    /**
     * 根据用户id查询所有该用户还没有领取优惠券的活动
     *
     * @param userid 用户id
     * @return
     */
    @Override
    public List<Couponactivity> getActivityListByUserId(Integer userid) {
        return couponactivityMapper.selectActiveListByUserId(userid);
    }

    /**
     * 根据活动id获取一条活动的详细信息,包含活动的优惠券列表
     *
     * @param activityid 活动id
     * @return
     */
    @Override
    public ActivityAndCouponlist getActivityAndCouponListById(Integer activityid) {
        //return couponactivityMapper.selectById(activityid);
        ActivityAndCouponlist activityAndCouponlist = new ActivityAndCouponlist();
        Couponactivity couponactivity = couponactivityMapper.selectById(activityid);
        List<Coupon> couponList = couponMapper.selectCouponListByActivityId(activityid);
        activityAndCouponlist.setCouponactivity(couponactivity);
        activityAndCouponlist.setCouponList(couponList);
        return activityAndCouponlist;
    }

    /**
     * 根据活动id和用户id查询一条活动的详细信息。包含活动的优惠券列表，但是有标记优惠券用户是否已经领取
     *
     * @param activityid 活动id
     * @param userid     用户id
     * @return
     */
    @Override
    public ActivityAndCouponlist getActivityAndCouponListByIdAndUserid(Integer activityid, Integer userid) {
        ActivityAndCouponlist activityAndCouponlist = new ActivityAndCouponlist();
        Couponactivity couponactivity = couponactivityMapper.selectById(activityid);
        //判断活动是否允许重复参加，并判断用户是否已经参加了活动
        if(couponactivity.getActiveallowedre()==2){
            //不允许重复参加，判断用户是否已经参与过该活动
            List<ActiveLog> listActiveLog = selectActiveLogByUserIdAdnActiveId(userid,activityid);
            if(listActiveLog!=null && listActiveLog.size()>0){
                for(ActiveLog log : listActiveLog){
                    if(log.getActivesharestate()==2){
                        //如果用户已经参与过活动了,标记couponfield1=1；
                        couponactivity.setCouponfiled1("1");
                    }
                }
            }
        }
        List<Coupon> couponList = couponMapper.selectCouponListByActivityId(activityid);
        //处理优惠券列表。判断优惠券是否可以重复领取。不可重复领取的优惠券，给出用户是否领取的标记
        for (Coupon c : couponList) {
            if (c.getCouponallowdre() == 2) {
                //不允许的情况下，需要判断用户是否已经领取
                List<Couponrecive> list = selectCouponReciveByUseridAndcouponid(userid, c.getCouponid());
                if (list != null && list.size() > 0) {
                    //已领取(备用字段1，设置未1，表示已经领取)
                    c.setCouponfiled1("1");
                }
            }
        }
        activityAndCouponlist.setCouponactivity(couponactivity);
        activityAndCouponlist.setCouponList(couponList);
        return activityAndCouponlist;
    }

    /**
     * 根据用户id和优惠券id查询用户是否有领取过该优惠券
     *
     * @param userid
     * @param couponid
     */
    private List<Couponrecive> selectCouponReciveByUseridAndcouponid(Integer userid, Integer couponid) {
        QueryWrapper<Couponrecive> wrapper = new QueryWrapper<>();
        wrapper.eq("couponid", couponid);
        wrapper.eq("couponreciveuserid", userid);
        return couponreciveMapper.selectList(wrapper);
    }

    /**
     * 根据活动id查询一条活动的详细信息
     *
     * @param activityid 活动id
     * @return
     */
    @Override
    public Couponactivity getActivityById(Integer activityid) {
        return couponactivityMapper.selectById(activityid);
    }

    /**
     * 添加活动参与记录
     *
     * @param activeLog
     * @return
     */
    @Override
    public int insertActiveLog(ActiveLog activeLog) {
        return activeLogMapper.insert(activeLog);
    }

    /**
     * 修改活动参与记录
     *
     * @param activeLog
     * @return
     */
    @Override
    public int updateActiveLog(ActiveLog activeLog) {
        return activeLogMapper.updateById(activeLog);
    }

    /**
     * 通过用户id和活动id查询用户是否有参与指定的活动
     *
     * @param userid
     * @param activeid
     * @return
     */
    @Override
    public List<ActiveLog> selectActiveLogByUserIdAdnActiveId(Integer userid, Integer activeid) {
        QueryWrapper<ActiveLog> wrapper = new QueryWrapper<>();
        wrapper.eq("cactivityid", activeid);
        wrapper.eq("activetouserid", userid);
        return activeLogMapper.selectList(wrapper);
    }

    /**
     * 判断分享活动是否有效
     *
     * @param activeid 活动id
     * @param pwd      活动参与密码
     * @return
     */
    @Override
    public ActiveLog checkActiveUrlUsed(Integer activeid, String pwd) {
        QueryWrapper<ActiveLog> wrapper = new QueryWrapper<>();
        wrapper.eq("cactivityid", activeid);
        wrapper.eq("activesharepwd", pwd);
        wrapper.eq("activesharestate", 1);
        List<ActiveLog> list = activeLogMapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 领取优惠券数据接口
     * 逻辑描述：
     * * 1、记录活动参与记录
     * * 1.1 判断是否有参数p，如果有，则还需要判断是否有pwd属性，如果有则进行修改活动参与记录；
     * * 1.2 如果没有p参数，或者没有pwd属性，则直接进行增加活动记录。
     * * 2、记录每一张优惠券的领取记录（如果couponfiled1=1，则不记录，不领取）
     * * 3、记录每一张优惠券的使用日志（记录领取日志。）
     *
     * @param activityAndCouponlist 加载活动详细信息时，从后端接收到的数据。重新传入到后台数据接口。
     * @param pwd                   课程领取密码
     * @return -1，活动已经领取； -3 领取活动失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized Map<String,String> drawCoupon(ActivityAndCouponlist activityAndCouponlist, Integer userid, String username, String pwd) {
        Map<String,String> map = new HashMap<>();
        map.put("code","1");
        map.put("msg","");
        //判断pwd是否存在
        try {
            if (pwd != null && !pwd.equals("")) {
                //判断活动是否已经领取
                ActiveLog activeLog = checkActiveIsDrawed(activityAndCouponlist.getCouponactivity().getCactivityid(), pwd);
                if (activeLog == null) {
                    //return -1;
                    map.put("code","-1");
                    map.put("msg","优惠券已经领取过，不能重复领取。");
                }
                //修改活动参与记录
                activeLog.setActivesharestate(2);
                activeLog.setActivetouserid(userid);
                activeLog.setActivetousername(username);
                activeLog.setActiverecivetime(new Date());
                activeLogMapper.updateById(activeLog);
            } else {
                //判断是否有现有活动没有参与，如果有则进行修改，没有则进行插入
                //根据用户id，活动id，状态进行查询
                ActiveLog activeLog = checkActiveByUserid(activityAndCouponlist.getCouponactivity().getCactivityid(),userid);
                if(activeLog != null){
                    activeLog.setActivesharestate(2);
                    activeLog.setActiverecivetime(new Date());
                    activeLogMapper.updateById(activeLog);
                }else {
                    //添加活动记录
                    activeLog = new ActiveLog();
                    activeLog.setCactivityid(activityAndCouponlist.getCouponactivity().getCactivityid());
                    activeLog.setActivesharestate(2);
                    activeLog.setActivetouserid(userid);
                    activeLog.setActivetousername(username);
                    activeLog.setActiverecivetime(new Date());
                    activeLogMapper.insert(activeLog);
                }
            }
            //记录优惠券的领取记录和日志
            for (Coupon coupon : activityAndCouponlist.getCouponList()) {
                //判断是否已经领取，如果已经领取，则不用再记录领取记录
                if (coupon.getCouponfiled1() != null && coupon.getCouponfiled1().equals("1")) {
                    map.put("msg",map.get("msg")+"优惠券："+coupon.getCoupontitle()+"已经领取过，不能重复领取；");
                    continue;
                }
                //修改优惠券的领取数量
                int rtnsavecount = saveCouponSendcount(coupon);
                if (rtnsavecount > 0) {
                    IdWorker idWorker = new IdWorker();
                    String couponno  = idWorker.nextId() + "";
                    //记录领取记录
                    Couponrecive recive = saveCouponRecive(coupon, userid, username, couponno);
                    //记录日志
                    saveCouponLog(coupon, userid, username, couponno, recive.getCouponreciveid(), activityAndCouponlist.getCouponactivity());
                }else{
                    //优惠券已领完
                    map.put("msg",map.get("msg")+"优惠券："+coupon.getCoupontitle()+"已经发放完，领取失败；");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code","-3");
            map.put("msg","领取优惠券失败，请重新领取或者联系管理员");
        }
        return map;
    }

    /**
     * 修改优惠券的领取数量
     *
     * @param coupon
     * @return -1,已经发放完毕
     */
    private int saveCouponSendcount(Coupon coupon) {
        //判断是否是无限量发放
        if (coupon.getCouponcount() != 0) {
            //先查询是否已经发放完毕
            coupon = couponMapper.selectById(coupon.getCouponid());
            if (coupon.getCouponcount() <= coupon.getCouponsendcount()) {
                return -1;
            }
        }
        coupon.setCouponsendcount(coupon.getCouponsendcount() + 1);
        coupon.setCouponfiled1(null);
        return couponMapper.updateById(coupon);
    }

    /**
     * 记录优惠券的领取记录
     *
     * @param coupon
     * @return
     */
    private Couponrecive saveCouponRecive(Coupon coupon, Integer userid, String username, String pwd) {
        Couponrecive recive = new Couponrecive();
        recive.setCouponid(coupon.getCouponid());
        recive.setCouponno(pwd);
        recive.setCouponreciveuserid(userid);
        recive.setCouponreciveusername(username);
        recive.setCouponrecivestate(1);
        recive.setCouponrecivetime(new Date());
        //判断优惠券的有效期
        if (coupon.getCouponeffectivetype() == 1) {
            //相对有效
            Calendar c = Calendar.getInstance();
            recive.setCouponrecivebegin(c.getTime());
            c.add(Calendar.DAY_OF_YEAR, coupon.getCouponeffective());
            recive.setCouponreciveend(c.getTime());
        } else if (coupon.getCouponeffectivetype() == 2) {
            //绝对有效
            recive.setCouponrecivebegin(coupon.getCouponstart());
            recive.setCouponreciveend(coupon.getCouponend());
        }
        //否则永不过期，则开始，结束时间为null
        couponreciveMapper.insert(recive);
        return recive;
    }

    /**
     * 记录优惠券的使用日志
     *
     * @param coupon
     * @param userid
     * @param username
     * @return
     */
    private int saveCouponLog(Coupon coupon, Integer userid, String username, String pwd, Integer recivid, Couponactivity couponactivity) {
        Couponlog log = new Couponlog();
        log.setCouponid(coupon.getCouponid());
        log.setCouponlongreciveid(recivid);
        log.setCouponno(pwd);
        log.setCouponloguserid(userid);
        log.setCouponlogusername(username);
        log.setCouponlogtype(1);
        log.setCouponlogtime(new Date());
        String str = "通过活动：" + couponactivity.getActivetitle() + "领取；活动id：" + couponactivity.getCactivityid();
        return couponlogMapper.insert(log);
    }

    /**
     * 判断活动是否已经被领取。未被领取则返回活动参与记录，否则返回null
     *
     * @param activeid
     * @param pwd
     * @return
     */
    private ActiveLog checkActiveIsDrawed(Integer activeid, String pwd) {
        QueryWrapper<ActiveLog> wrapper = new QueryWrapper<>();
        wrapper.eq("cactivityid", activeid);
        wrapper.eq("activesharepwd", pwd);
        wrapper.eq("activesharestate", 1);
        List<ActiveLog> list = activeLogMapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 根据用户id和活动id查询活动记录（用于判断用户是否已经绑定了指定的活动）
     *
     * @param activeid
     * @param userid
     * @return
     */
    private ActiveLog checkActiveByUserid(Integer activeid, Integer userid) {
        QueryWrapper<ActiveLog> wrapper = new QueryWrapper<>();
        wrapper.eq("cactivityid", activeid);
        wrapper.eq("activetouserid", userid);
        wrapper.eq("activesharestate", 1);
        List<ActiveLog> list = activeLogMapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
}
